package com.gps.skyrc.activity;

import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleReadCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;
import com.clj.fastble.utils.HexUtil;
import com.gps.skyrc.R;
import com.gps.skyrc.activity.base.BaseActivity;
import com.gps.skyrc.api.Config;
import com.gps.skyrc.api.EventBusCode;
import com.gps.skyrc.bean.DeviceInfo;
import com.gps.skyrc.bean.EventBusMessage;
import com.gps.skyrc.bean.testBean;
import com.gps.skyrc.data.ParseData;
import com.gps.skyrc.tool.CustomDialog;
import com.gps.skyrc.tool.DensityUtils;
import com.gps.skyrc.tool.EventBusUtils;
import com.gps.skyrc.tool.MyTitleBar;
import com.gps.skyrc.tool.PromptDialog;
import com.gps.skyrc.tool.RxTimerUtil;
import com.gps.skyrc.tool.SharedPreferencesUtils;
import com.gps.skyrc.tool.ShowNameDialog;
import com.gps.skyrc.tool.Tip;
import com.gps.skyrc.tool.logger.ILogger;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.OnNeverAskAgain;
import permissions.dispatcher.OnPermissionDenied;
import permissions.dispatcher.OnShowRationale;
import permissions.dispatcher.PermissionRequest;
import permissions.dispatcher.RuntimePermissions;

@RuntimePermissions
public class MainActivity extends BaseActivity implements View.OnClickListener {
    @BindView(R.id.title_setting_iv)
    ImageView mTitleSettingIv;
    @BindView(R.id.title_btn_iv)
    ImageView mTitleBtnIv;
    @BindView(R.id.read_result_tv)
    TextView mReadResultTv;
    @BindView(R.id.beeline_mode_iv)
    ImageView mBeelineModeIv;
    @BindView(R.id.track_mode_iv)
    ImageView mTrackModeIv;
    @BindView(R.id.fly_mode_iv)
    ImageView mFlyModeIv;
    @BindView(R.id.seek)
    View mViewBg;
    @BindView(R.id.view_show)
    View mView;
    @BindView(R.id.bluetooth_iv)
    ImageView mBluetoothIv;
    @BindView(R.id.bluetooth_point_iv)
    ImageView mBluetoothPointIv;
    @BindView(R.id.dhop_iv)
    ImageView mDhopIv;
    @BindView(R.id.dhop_point_iv)
    ImageView mDhopPointIv;
    @BindView(R.id.electricity_iv)
    ImageView mElectricityIv;
    @BindView(R.id.electricity_num_tv)
    TextView melectricityNumTv;
    @BindView(R.id.beeline_mode_ing_tv)
    TextView mBeelineModeingTv;
    @BindView(R.id.track_mode_ing_tv)
    TextView mTrackModeingTv;
    @BindView(R.id.fly_mode_ing_tv)
    TextView mFlyModeingTv;
    @BindView(R.id.red_point_new_msg_iv)
    ImageView mRedPointIv;
    @BindView(R.id.hdop_num_tv)
    TextView mHdopNumTv;
    @BindView(R.id.start_btn_ll)
    LinearLayout mStartBtn;
    @BindView(R.id.start_btn_tv)
    TextView mStartBtnTv;
    @BindView(R.id.read_data_rl)
    RelativeLayout mReadBtn;
    @BindView(R.id.test_time)
    TextView testTime;
    @BindView(R.id.test_speed)
    TextView testSpeed;
    @BindView(R.id.test_slope)
    TextView testSlope;
    @BindView(R.id.test_max_speed)
    TextView testMaxSpeed;

    private ArrayList<DeviceInfo> mDeviceInfos;
    private ShowNameDialog mShowNameDialog;
    private DeviceInfo mShowInfo;
    private String mLastMac;
    private BleDevice mSendBleDevice;
    private int chooseMode = 0;//0默认  1赛道  2飞行

    @Override
    protected void getLayout() {
        setContentView(R.layout.activity_main);

    }

    @Override
    protected void setTitleBar() {
        mTitleSettingIv.setOnClickListener(v -> {
            RxTimerUtil.cancel();
            Tip.showLoadDialog(mContext);
            new Handler().postDelayed(() -> {
                Tip.closeLoadDialog();
                Bundle bundle = new Bundle();
                int offline = 0;//0离线  1在线
                if (null != mSendBleDevice) {
                    offline = 1;
                    bundle.putInt("offLine", offline);
                    bundle.putParcelable("deviceInfo", mShowInfo);
                    bundle.putParcelable(Config.BLE_SEND_BLEDEVICE, mSendBleDevice);
                    save();
                } else {
                    bundle.putInt("offLine", offline);
                }
                startActivity(AppSettingActivity.class, bundle);
            }, 1000);
        });

        mTitleBtnIv.setOnClickListener(v -> {
            Tip.showLoadDialog(mContext);
            if (mShowInfo.getGpsBtnStatue() == 0) {
                setGpsCheck(0);
            } else {
                setGpsCheck(1);
            }
        });

    }

    private void setGpsCheck(int statue) {
        new Handler().postDelayed(() -> {
            byte[] cmd = {0x0f, 0x05, 0x0A, 0, 0, 0, 0, (byte) 0xff, (byte) 0xff};
            if (statue == 0)
                cmd[4] = 0x01;
            int checksum = 1;
            for (int i = 2; i < 6; i++)
                checksum += cmd[i];
            cmd[6] = (byte) (checksum & 0xFF);
            BleManager.getInstance().write(mSendBleDevice, Config.UUID_SERVICE, Config.UUID_WRITE, cmd, new BleWriteCallback() {
                @Override
                public void onWriteSuccess(int current, int total, byte[] justWrite) {
                    Tip.closeLoadDialog();
                }

                @Override
                public void onWriteFailure(BleException exception) {
                    Tip.closeLoadDialog();
                    Tip.showToast(mContext, R.string.send_error);
                }
            });
        }, 1000);
    }

    @Override
    protected void init() {
        mLastMac = (String) SharedPreferencesUtils.getParam(mContext, SharedPreferencesUtils.PreKey.LAST_DEVICE_MAC, "");
        Tip.showLoadDialog(mContext);
        mBluetoothIv.setEnabled(false);//一开始就不可点击
        checkPermission();
        mStartBtn.setOnClickListener(this);
        mReadBtn.setOnClickListener(this);
        mBeelineModeIv.setOnClickListener(this);
        mTrackModeIv.setOnClickListener(this);
        mFlyModeIv.setOnClickListener(this);
        mBluetoothIv.setOnClickListener(this);
        //右边需要跳转带Bledevice参数 先不可点击
        mTitleSettingIv.setEnabled(false);
        mTitleBtnIv.setEnabled(false);
    }

    @Override
    protected boolean isRegisterEventBus() {
        return true;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start_btn_ll:
                if (mStartBtnTv.getText().toString().trim().equals(getResources().getString(R.string.start))) {
                    if (chooseMode == 1 || chooseMode == 2) {
                        if (mShowInfo.getSatelliteNum() >= 4) {
                            startBtn();
                        } else {
                            PromptDialog promptDialog = new PromptDialog(mContext, getResources().getString(R.string.satellite_signal_weak));
                            promptDialog.show();
                            promptDialog.setConfirmClickListener(promptDialog::dismiss);

                        }
                    }
                } else if (mStartBtnTv.getText().toString().trim().equals(getResources().getString(R.string.end))) {
                    stopBtn();
                }
                break;
            case R.id.read_data_rl:
                save();
                RxTimerUtil.cancel();
                Tip.showLoadDialog(mContext);
                new Handler().postDelayed(new Runnable() {//延迟是为了等定时器请求内容完全取消
                    @Override
                    public void run() {
                        Tip.closeLoadDialog();
                        Bundle bundle1 = new Bundle();
                        bundle1.putString("which", "main");
                        bundle1.putParcelable(Config.BLE_SEND_BLEDEVICE, mSendBleDevice);
                        bundle1.putParcelable("deviceInfo", mShowInfo);
                        startActivity(TestDetailActivity.class, bundle1);
                    }
                }, 1000);
                break;
            case R.id.beeline_mode_iv:
                save();
                Bundle bundle = new Bundle();
                bundle.putInt("satellites_num", Integer.valueOf(mHdopNumTv.getText().toString().trim()));
                bundle.putParcelable(Config.BLE_SEND_BLEDEVICE, mSendBleDevice);
                startActivity(BeelineModeActivity.class, bundle);
                break;
            case R.id.track_mode_iv:
                if (chooseMode == 1) {
                    chooseMode = 0;
                    mTrackModeIv.setBackground(getResources().getDrawable(R.drawable.circle_gray_bg));
                    mStartBtn.setEnabled(false);
                } else {
                    chooseMode = 1;
                    mTrackModeIv.setBackground(getResources().getDrawable(R.drawable.circle_blue_bg));
                    mFlyModeIv.setBackground(getResources().getDrawable(R.drawable.circle_gray_bg));
                    //每秒一次的hdop查询会直接覆盖
                }
                break;
            case R.id.fly_mode_iv:
                if (chooseMode == 2) {
                    chooseMode = 0;
                    mFlyModeIv.setBackground(getResources().getDrawable(R.drawable.circle_gray_bg));
                    mStartBtn.setEnabled(false);
                } else {
                    chooseMode = 2;
                    mFlyModeIv.setBackground(getResources().getDrawable(R.drawable.circle_blue_bg));
                    mTrackModeIv.setBackground(getResources().getDrawable(R.drawable.circle_gray_bg));
                    //每秒一次的hdop查询会直接覆盖
                }
                break;
            case R.id.bluetooth_iv:
                Tip.showLoadDialog(mContext);
                startScan();
                break;

        }
    }

    //开始按钮
    private void startBtn() {
        Tip.showLoadDialog(mContext);
        new Handler().postDelayed(() -> {//延迟是为了等定时器请求内容完全取消
            byte[] cmd = {0x0f, 0x05, 0x03, 0, 0, 0, 0, (byte) 0xff, (byte) 0xff};
            if (chooseMode == 1)
                cmd[4] = 0x02;
            else if (chooseMode == 2)
                cmd[4] = 0x03;
            int checksum = 1;
            for (int i = 2; i < 6; i++)
                checksum += cmd[i];
            cmd[6] = (byte) (checksum & 0xFF);
            BleManager.getInstance().write(mSendBleDevice, Config.UUID_SERVICE, Config.UUID_WRITE, cmd, new BleWriteCallback() {
                @Override
                public void onWriteSuccess(int current, int total, byte[] justWrite) {
                    Tip.closeLoadDialog();
                    ILogger.d("发送" + cmd[4] + "成功");
                    //查询dhop很快  所以交给它来变化
                }

                @Override
                public void onWriteFailure(BleException exception) {
                    ILogger.e(exception.toString());
                    Tip.closeLoadDialog();
                    Tip.showToast(mContext, R.string.send_error);
                }
            });
        }, 1000);
    }

    //停止按钮
    private void stopBtn() {
        Tip.showLoadDialog(mContext);
        new Handler().postDelayed(() -> {//延迟是为了等定时器请求内容完全取消
            byte[] cmd = {0x0f, 0x05, 0x09, 0, 0, 0, 0, (byte) 0xff, (byte) 0xff};
            cmd[4] = (byte) mShowInfo.getTestMode();
            int checksum = 1;
            for (int i = 2; i < 6; i++)
                checksum += cmd[i];
            cmd[6] = (byte) (checksum & 0xFF);
            BleManager.getInstance().write(mSendBleDevice, Config.UUID_SERVICE, Config.UUID_WRITE, cmd, new BleWriteCallback() {
                @Override
                public void onWriteSuccess(int current, int total, byte[] justWrite) {
                    Tip.closeLoadDialog();
                    ILogger.d("停止成功");
                }

                @Override
                public void onWriteFailure(BleException exception) {
                    Tip.closeLoadDialog();
                    Tip.showToast(mContext, R.string.send_error);
                }
            });
        }, 1000);

    }

    private void checkPermission() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!bluetoothAdapter.isEnabled()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, 0x01);
            return;
        }
        MainActivityPermissionsDispatcher.showLocationWithPermissionCheck(this);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 0x01) {
            if (resultCode == Activity.RESULT_OK) {
                MainActivityPermissionsDispatcher.showLocationWithPermissionCheck(this);
            } else if (resultCode == Activity.RESULT_CANCELED) {
                Tip.showToast(mContext, R.string.open_ble);
            }
        }
    }


    @NeedsPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
    void showLocation() {
        mDeviceInfos = new ArrayList<>();
        setScanRule();
        startScan();
    }

    /**
     * 订阅eventbus事件
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onSubEventBus(EventBusMessage message) {
        int code = message.getCode();
    }

    private void setScanRule() {
        BleScanRuleConfig builder = new BleScanRuleConfig.Builder()
                .setDeviceName(true, Config.BLE_DEVICE_NAME)
                .setScanTimeOut(5000)
                .build();
        BleManager.getInstance().initScanRule(builder);
    }

    private void startScan() {
        mDeviceInfos.clear();
        BleManager.getInstance().scan(new BleScanCallback() {
            @Override
            public void onScanFinished(List<BleDevice> scanResultList) {
                // 扫描结束，列出所有扫描到的符合扫描规则的BLE设备（主线程）
                //弹窗出来
                ILogger.d("finish" + scanResultList.size());
                for (int i = 0; i < scanResultList.size(); i++) {
                    if (scanResultList.get(i).getMac().equals(mLastMac))
                        for (int k = 0; k < mDeviceInfos.size(); k++) {
                            if (mDeviceInfos.get(k).getMac().equals(mLastMac)) {
                                connect(mDeviceInfos.get(k), scanResultList.get(i));
                                return;
                            }
                        }
                }
                showChoose(scanResultList);
            }

            @Override
            public void onScanStarted(boolean success) {
                // 开始扫描（主线程）
                ILogger.d("start scan boolean:" + success);
            }

            @Override
            public void onScanning(BleDevice bleDevice) {
                // 扫描到一个符合扫描规则的BLE设备（主线程）
                ILogger.d("find a new one :" + bleDevice.toString());
                //有新的就添加 否则返回
                if (mDeviceInfos != null) {
                    for (DeviceInfo deviceInfo : mDeviceInfos) {
                        if (deviceInfo.getMac().equals(bleDevice.getMac())) {
                            return;
                        }
                    }
                }
                DeviceInfo deviceInfo = new DeviceInfo();
                deviceInfo.setMac(bleDevice.getMac());
//                deviceInfo.save();
                mDeviceInfos.add(deviceInfo);
            }
        });
    }

    private void connect(DeviceInfo info, BleDevice bleDevice) {
        BleManager.getInstance().connect(bleDevice, new BleGattCallback() {
            @Override
            public void onStartConnect() {

            }

            @Override
            public void onConnectFail(BleDevice bleDevice, BleException exception) {
                ILogger.e("连接失败");
                Tip.closeLoadDialog();
                Tip.showToast(mContext, getResources().getString(R.string.connect_error));
                RxTimerUtil.cancel();
                info.setLine(false);
                mSendBleDevice = null;
                mBluetoothIv.setEnabled(true);
                setOffline();
                new Handler().postDelayed(() -> connect(info, bleDevice), 2000);
            }

            @Override
            public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
                ILogger.d("连接成功");
                Tip.closeLoadDialog();
                mBluetoothIv.setEnabled(false);
                mShowInfo = info;//展示表明选择中的是哪个INFO，以后数据好保存
                //连接成功 表明其他按钮可以点击  记录bleDevice  需要传出去
                mSendBleDevice = bleDevice;
                mTitleSettingIv.setEnabled(true);
                mTitleBtnIv.setEnabled(true);
                //连接成功就开启监听
                openNotify(bleDevice);
                //获取名字  HDOP基本参数 保存sp
                SharedPreferencesUtils.setParam(mContext, SharedPreferencesUtils.PreKey.LAST_DEVICE_MAC, info.getMac());


            }

            @Override
            public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) {
                if (!isActiveDisConnected) {//非主动断开连接
                    info.setLine(false);
                    RxTimerUtil.cancel();
                    mSendBleDevice = null;
                    setOffline();
                    connect(info, device);
                }
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mSendBleDevice != null && mShowInfo != null) {
            RxTimerUtil.cancel();
            RxTimerUtil.interval(1000, new RxTimerUtil.IRxNext() {
                @Override
                public void doNext(long number) {
                    readHdop(mShowInfo, mSendBleDevice);//循环
                }
            });
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        RxTimerUtil.cancel();
    }

    //离线状态
    private void setOffline() {
        mBluetoothIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_bluetooth_offline));
        mBluetoothPointIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_ble_circle4));
        mDhopIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_gps_offline));
        mDhopPointIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_ble_circle4));
        mElectricityIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_electricity_off));
        melectricityNumTv.setVisibility(View.INVISIBLE);
        mBeelineModeIv.setEnabled(false);
        mTrackModeIv.setEnabled(false);
        mFlyModeIv.setEnabled(false);
        mStartBtn.setEnabled(false);
        mReadBtn.setEnabled(false);
        mReadBtn.setBackground(getResources().getDrawable(R.drawable.circle_gray_bg));
        mRedPointIv.setVisibility(View.INVISIBLE);
        mStartBtn.setBackground(getResources().getDrawable(R.drawable.circle_gray_bg));
        mHdopNumTv.setText("0");
        mTitleBtnIv.setEnabled(false);
        mTitleBtnIv.setImageDrawable(getResources().getDrawable(R.mipmap.btn_off));

        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mView.getLayoutParams();
        layoutParams.width = mViewBg.getMeasuredWidth();
        layoutParams.height = DensityUtils.dip2px(mContext, 10);
        mView.setBackgroundColor(getResources().getColor(R.color.hdop_bg));
        mView.setLayoutParams(layoutParams);
    }

    private int dataLength; /* 返回数据的长度,一包只有20字节*/
    private int lastPos; /* 当前返回的是一条协议里的第几个字节*/
    private byte[] procmd;

    //开启监听
    private void openNotify(BleDevice bleDevice) {
        BleManager.getInstance().notify(bleDevice, Config.UUID_SERVICE, Config.UUID_NOTIFY, new BleNotifyCallback() {
            @Override
            public void onNotifySuccess() {
                // 打开通知操作成功
                ILogger.d("打开通知操作成功");
                readDeviceName(mShowInfo, bleDevice);
            }

            @Override
            public void onNotifyFailure(BleException exception) {
                // 打开通知操作失败
                ILogger.d("打开通知操作失败");
            }

            @Override
            public void onCharacteristicChanged(byte[] data) {
                // 打开通知后，设备发过来的数据将在这里出现
                runOnUiThread(() -> {
                    ILogger.d(HexUtil.formatHexString(data, true));
                    if (lastPos == 0 && data[0] == 0x0F) {
                        if (data[2] == 0x02 || data[2] == 0x07) {
                            dataLength = (data[3] & 0xFF) * 256 + (data[1] & 0xFF) + 4;
                        } else
                            dataLength = (data[1] & 0xFF) + 4;
                        procmd = new byte[dataLength];
                        System.arraycopy(data, 0, procmd, 0, data.length);
                    } else if (lastPos != 0) { /* 一条协议没有接收完*/
                        System.arraycopy(data, 0, procmd, lastPos, data.length);
                    }
                    lastPos += data.length;
                    if (dataLength != 0 && dataLength == lastPos) { /* 一条协议接受完成*/
                        dataLength = lastPos = 0;
                        ILogger.d("da:" + Arrays.toString(procmd));
                        switch (procmd[2]) {
                            case 0x01://设置直线 响应 可以不写
//                                EventBusUtils.post(new EventBusMessage<>(EventBusCode.EVENT_BUS_READ_DATA, procmd));
                                break;
                            case 0x02://获取直线测试数据   响应
                                EventBusUtils.post(new EventBusMessage<>(EventBusCode.EVENT_BUS_READ_DATA, procmd));
                                break;
                            case 0x03://设置赛道、飞行开始 可以不写

                                break;
                            case 0x04://获取赛道飞行数据  响应
                                EventBusUtils.post(new EventBusMessage<>(EventBusCode.EVENT_BUS_READ_DATA, procmd));
                                break;
                            case 0x05://获取修改名字  响应
                                EventBusUtils.post(new EventBusMessage<>(EventBusCode.EVENT_BUS_NAME_MODIFY, procmd));
                                break;
                            case 0x06://历史列表
                                EventBusUtils.post(new EventBusMessage<>(EventBusCode.EVENT_BUS_HISTORY_LIST, procmd));
                                break;
                            case 0x07://获取历史单条详情
                                EventBusUtils.post(new EventBusMessage<>(EventBusCode.EVENT_BUS_READ_DATA, procmd));
                                break;
                            case 0x08://清除设备缓存   响应
                                EventBusUtils.post(new EventBusMessage<>(EventBusCode.EVENT_BUS_CLEAN_CACHE_RESPONE, procmd));
                                break;
                        }
                    }
                });
            }
        });
    }

    //获取基本信息
    private void readHdop(DeviceInfo info, BleDevice bleDevice) {
        BleManager.getInstance().read(bleDevice, Config.UUID_SERVICE, Config.UUID_READ_HDOP, new BleReadCallback() {
            @Override
            public void onReadSuccess(byte[] data) {//已经转成10进制
                ILogger.d(Arrays.toString(data));
                DeviceInfo deviceInfo = ParseData.parsehdop(info, data);
                deviceInfo.setLine(true);
                mShowInfo = deviceInfo;
                toShow(deviceInfo);
                readTest(info, bleDevice);
            }

            @Override
            public void onReadFailure(BleException exception) {
                ILogger.e(exception.toString());
            }
        });
    }

    private void readTest(DeviceInfo info, BleDevice bleDevice) {
        BleManager.getInstance().read(bleDevice, Config.UUID_SERVICE, Config.UUID_TEST, new BleReadCallback() {
            @Override
            public void onReadSuccess(byte[] data) {
//                ILogger.d(Arrays.toString(data));
                testBean testBean = ParseData.parseTest(data);
                showTest(testBean);
            }

            @Override
            public void onReadFailure(BleException exception) {
                ILogger.e(exception.toString());
            }
        });
    }

    private void showTest(testBean testBean) {
        testTime.setText(testBean.getTime());
        testSpeed.setText(testBean.getSpeed() + "km/h");
        testSlope.setText(testBean.getSlope() + "");
        testMaxSpeed.setText(testBean.getMaxSpeed() + "km/h");
    }

    //显示DHOP数据内容
    private void toShow(DeviceInfo deviceInfo) {
        double hdop = deviceInfo.getHdop();

        //蓝牙图片  电量显示  模式选择  是否能够点击  是否有新数据  DHOP进度条
        mBluetoothIv.setImageDrawable(deviceInfo.isLine() ?
                getResources().getDrawable(R.mipmap.img_bluetooth_online) :
                getResources().getDrawable(R.mipmap.img_bluetooth_offline));
        mDhopIv.setImageDrawable(deviceInfo.isLine() ?
                getResources().getDrawable(R.mipmap.img_gps_online) :
                getResources().getDrawable(R.mipmap.img_gps_offline));

        mElectricityIv.setImageDrawable(deviceInfo.isLine() ?
                getResources().getDrawable(R.mipmap.img_gps_online) :
                getResources().getDrawable(R.mipmap.img_gps_offline));
        mBluetoothPointIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_ble_circle1));
        //电量
        melectricityNumTv.setVisibility(View.VISIBLE);
        if (deviceInfo.getVoltagePercent() <= 20)
            mElectricityIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_electricity_low));
        else
            mElectricityIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_electricity_50));
        melectricityNumTv.setText(deviceInfo.getVoltagePercent() + "%");

        //gps开关
        mTitleBtnIv.setImageDrawable(deviceInfo.getGpsBtnStatue() == 0 ? getResources().getDrawable(R.mipmap.btn_on) : getResources().getDrawable(R.mipmap.btn_off));

        if (deviceInfo.getIsTesting() == 0) {
            //未测试  按钮可点
            setEnable(true);
            mBeelineModeingTv.setVisibility(View.INVISIBLE);
            mTrackModeingTv.setVisibility(View.INVISIBLE);
            mFlyModeingTv.setVisibility(View.INVISIBLE);
            mStartBtnTv.setText(getString(R.string.start));
            mReadBtn.setEnabled(true);
            mReadBtn.setBackground(getResources().getDrawable(R.drawable.circle_blue_bg));
        } else if (deviceInfo.getIsTesting() == 1) {
            //测试中
            setEnable(false);
            chooseModeing(deviceInfo.getTestMode());
            mStartBtnTv.setText(getString(R.string.end));
            mReadBtn.setEnabled(false);
            mReadBtn.setBackground(getResources().getDrawable(R.drawable.circle_gray_bg));
        }

        if (deviceInfo.getIsHaveNewMsg() == 0)
            mRedPointIv.setVisibility(View.INVISIBLE);
        else
            mRedPointIv.setVisibility(View.VISIBLE);

        mHdopNumTv.setText(deviceInfo.getSatelliteNum() + "");

        //HDOP进度条
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mView.getLayoutParams();
        if (hdop > 10)
            hdop = 10;
        layoutParams.width = (int) (hdop / 10 * mViewBg.getMeasuredWidth());
        layoutParams.height = DensityUtils.dip2px(mContext, 10);
        if (hdop == 0) {
            //hdop值为0时卫星数必定为0
            mView.setBackgroundColor(getResources().getColor(R.color.hdop_bg));
            mDhopPointIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_ble_circle4));
        } else if (hdop <= 1) {
            mView.setBackgroundColor(getResources().getColor(R.color.hdop_green));
            mDhopPointIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_ble_circle1));
        } else if (hdop <= 2) {
            mView.setBackgroundColor(getResources().getColor(R.color.hdop_yellow));
            mDhopPointIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_ble_circle1));
        } else if (hdop <= 5) {
            mView.setBackgroundColor(getResources().getColor(R.color.hdop_orange));
            mDhopPointIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_ble_circle2));
        } else {
            mView.setBackgroundColor(getResources().getColor(R.color.hdop_red));
            mDhopPointIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_ble_circle3));
        }
        if (deviceInfo.getSatelliteNum() == 0) {
            mDhopPointIv.setImageDrawable(getResources().getDrawable(R.mipmap.img_ble_circle4));
        }
        mView.setLayoutParams(layoutParams);
    }

    //正在的哪个模式下
    private void chooseModeing(int testMode) {
        mBeelineModeingTv.setVisibility(testMode == 0 ? View.VISIBLE : testMode == 1 ? View.VISIBLE : View.INVISIBLE);
        mTrackModeingTv.setVisibility(testMode == 2 ? View.VISIBLE : View.INVISIBLE);
        mFlyModeingTv.setVisibility(testMode == 3 ? View.VISIBLE : View.INVISIBLE);
    }

    private void setEnable(boolean isWorking) {
        mBeelineModeIv.setEnabled(isWorking);
        mTrackModeIv.setEnabled(isWorking);
        mFlyModeIv.setEnabled(isWorking);
        mStartBtn.setEnabled(true);//未测试 可点（已在按钮处判断），测试中，也可以点(可以暂停)
        if (chooseMode == 1 || chooseMode == 2)//模式已选中
            mStartBtn.setBackground(getResources().getDrawable(R.drawable.circle_blue_bg));
        else
            mStartBtn.setBackground(isWorking ? getResources().getDrawable(R.drawable.circle_gray_bg) :
                    getResources().getDrawable(R.drawable.circle_blue_bg));
    }

    private void readDeviceName(DeviceInfo deviceInfo, BleDevice bleDevice) {
        BleManager.getInstance().read(bleDevice, Config.UUID_SERVICE, Config.UUID_READ_NAME, new BleReadCallback() {
            @Override
            public void onReadSuccess(byte[] data) {//已经转成10进制
                ILogger.d("basic:" + Arrays.toString(data));
                try {
                    String name = new String(data, "UTF-8");
                    deviceInfo.setName(name);
                    ILogger.d("basic name:" + name);
                    getVersion(deviceInfo, bleDevice);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onReadFailure(BleException exception) {
                ILogger.e(exception.toString());
                Tip.showToast(mContext, R.string.get_error);
            }
        });
    }

    //弹框选择哪个设备 选择了再连接

    private void showChoose(List<BleDevice> scanResultList) {
        Tip.closeLoadDialog();
        mShowNameDialog = new ShowNameDialog(mContext, mDeviceInfos);
        mShowNameDialog.show();
        mShowNameDialog.setDeviceChooseClickListener(new ShowNameDialog.onDeviceChooseClickListener() {
            @Override
            public void onCancel() {
                mShowNameDialog.dismiss();
                setOffline();
                mBluetoothIv.setEnabled(true);
                if (!mLastMac.equals(""))
                    mTitleSettingIv.setEnabled(true);
            }

            @Override
            public void onItemClick(DeviceInfo info, int position) {

                mShowNameDialog.dismiss();
                Tip.showLoadDialog(mContext);
                connect(info, scanResultList.get(position));
            }
        });
    }

    private void save() {
        for (DeviceInfo info : mDeviceInfos) {//app退出保存到数据库
            if (mShowInfo != null) {
                if (mShowInfo.getMac().equals(info.getMac())) {
                    ILogger.e("保存数据");
                    mShowInfo.save();
                }
            }
        }
    }

    //查看设备版本
    private void getVersion(DeviceInfo info, BleDevice bleDevice) {
        BleManager.getInstance().read(bleDevice, Config.UUID_SERVICE, Config.UUID_VERSION_UPGRADE, new BleReadCallback() {
            @Override
            public void onReadSuccess(byte[] data) {//已经转成10进制
                Float version = ParseData.parseVersion(data);
                info.setVersion(version);
                ILogger.d("version code:" + Arrays.toString(data) + "/ " + version);
                RxTimerUtil.cancel();
                RxTimerUtil.interval(1000, new RxTimerUtil.IRxNext() {
                    @Override
                    public void doNext(long number) {
                        readHdop(info, bleDevice);//循环
                    }
                });
            }

            @Override
            public void onReadFailure(BleException exception) {
                Tip.showToast(mContext, R.string.get_version_error);
            }
        });
    }

    /**
     * 监听系统返回按键
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            CustomDialog.Builder builder = new CustomDialog.Builder(this);
            builder.setMessage(R.string.quit_app);
            builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
                dialog.dismiss();
                onDefaultFinish();
            });
            builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
            builder.create().show();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
    }

    @OnShowRationale(Manifest.permission.ACCESS_COARSE_LOCATION)
    void showRationaleForExternal(final PermissionRequest request) {
        //注册一些解释为什么需要权限的方法。
        Tip.showToast(mContext, R.string.permission_rationale);
        request.proceed();
    }

    @OnPermissionDenied(Manifest.permission.ACCESS_COARSE_LOCATION)
    void showDeniedForExternal() {
        //注册一些需要权限的方法。
        Tip.showToast(this, R.string.permission_rationale);
    }

    @OnNeverAskAgain(Manifest.permission.ACCESS_COARSE_LOCATION)
    void showNeverAskForExternal() {
        //注册一些处理用户选择的方法以永久拒绝权限。
        Tip.showToast(this, R.string.permission_never_ask_again);
    }

}
